<template>
  <div class="tree-form" ref="split">
    <div class="left-view" ref="leftView">
      <el-scrollbar ref="treeScroll" v-loading="loadTree">
        <el-tree ref="treeRef" :data="treeData" :highlight-current="true"
          :props="{ label: 'name', children: 'testCases' }" node-key="id" :expand-on-click-node="false"
          :check-on-click-leaf="false" default-expand-all :default-checked-keys="defaultCheckKeys" show-checkbox
          icon-class="el-icon-arrow-right" :current-node-key="currentItem.id" @node-click="handleNodeClick">
          <template #default="{ data }">
            <div class="custom-tree-node">
              <!-- 原来逻辑直接迁移表现结果不一致，因此作出如下调整 -->
              <span v-html="data.testCases ? folderIcon : nodeIcon"></span>
              <TooltipBox :content="data.name" :tooltipAttrs="{ placement: 'right', offset: 38 }" />
            </div>
          </template>
        </el-tree>
      </el-scrollbar>
    </div>
    <div class="right-view" ref="rightView">
      <NodeTree :isLoading="configLoading" class="node-tree" ref="nodeTreeRef" :data="nodeData" />
      <div class="btn-box">
        <el-button type="primary" size="large" @click="emit('prev')">上一步</el-button>
        <el-button type="primary" size="large" :loading="btnLoading" @click="handleFinish">完 成</el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import Split from "split.js";
import { getTestCaseTree, getTestCaseConfig, updateTestCaseConfig, completeCreateTask, setSelectCases, routerLinkTestView } from "../../api/task/index";
import type { TestCaseTreeItem, TestCaseItem, CreateTaskParams } from "../../api/task/index.d";
import folderIcon from "../../assets/svg/task/folder.svg?raw";
import nodeIcon from "../../assets/svg/task/node.svg?raw";

import { nodeItem, NodeTree, TooltipBox } from "../../common/index.js";
import "../../common/style.css";

import { ElTree, ElMessage, ElMessageBox } from "element-plus";
import type { TreeKey } from "element-plus/lib";
type CaseType = TestCaseTreeItem | TestCaseItem;
const props = withDefaults(defineProps<{ taskInfo: Partial<CreateTaskParams> }>(), {
  taskInfo: () => ({})
});
const emit = defineEmits(["prev", "reset"]);
const leftView = ref<HTMLElement>();
const rightView = ref<HTMLElement>();
const treeRef = ref<InstanceType<typeof ElTree>>();
const nodeTreeRef = ref<InstanceType<typeof NodeTree>>();

const loadTree = ref(false);
const treeData = ref<CaseType[]>([]);
const currentItem = ref<Partial<CaseType>>({}); // 当前选中节点
const defaultCheckKeys = ref<string[]>([]); // 默认勾选的节点

const nodeData = ref<nodeItem[]>([]); // 右侧配置数据
const configLoading = ref(false); // 右侧配置加载状态
const btnLoading = ref(false); // 完成按钮加载状态
const oldDataString = ref("[]");

onMounted(async () => {
  initSplit();
  getTreeData();
});
const initSplit = () => {
  const options = [{ el: [leftView.value, rightView.value], direction: "horizontal", sizes: [20, 80] }];
  options.forEach((x: any) => {
    Split(x.el, {
      snapOffset: 0,
      gutterSize: 10,
      sizes: x.sizes,
      direction: x.direction,
      onDragEnd: () => {
        console.log("拖动结束");
      }
    });
  });
};

/**
 * @description: 获取测试例树结构
 * @return {*}
 */
const getTreeData = async (isUpdate = false) => {
  !isUpdate && (loadTree.value = true);
  const { data } = await getTestCaseTree({}, { taskId: props.taskInfo.id });

  treeData.value = data ? [{ ...data, children: handleData(data) }] : [];
  if (!isUpdate) {
    // !currentItem.value.id && findFirstChild(treeData.value);
    !currentItem.value.id && (currentItem.value = treeData.value?.[0] || []);
    getNodeData();
    defaultCheckKeys.value = treeData.value.map((it) => it.id);
    loadTree.value = false;
  }
  console.log("树结构数据", treeData.value);
};
/**
 * @description: 获取测试例配置
 * @return {*}
 */
const getNodeData = async () => {
  configLoading.value = true;
  const { data } = await getTestCaseConfig({ caseId: currentItem.value.id || "" }, { taskId: props.taskInfo.id });
  configLoading.value = false;
  nodeData.value = data || [];
  oldDataString.value = JSON.stringify(nodeData.value);
};

/**
 * @description: 测试例数据处理
 * @param {*} data
 * @return {*}
 */
const handleData = (data: any) => {
  const caseList = [...(data.testCases || []), ...(data.childCase || [])].map((it) => {
    return { ...it, isCase: true };
  });
  let children: CaseType[] = [...(data.childTree || []), ...caseList];
  if (children.length) {
    children = children.map((item) => {
      return { ...item, children: handleData(item) };
    });
  }
  return children;
};

// /**
//  * @description: 查找第一个子节点
//  * @param {*} data
//  * @return {*}
//  */
// const findFirstChild = (data: CaseType[]) => {
//   for (let i = 0; i < data.length; i++) {
//     const children = data[i].children;
//     if (Array.isArray(children) && children.length) {
//       findFirstChild(children);
//     } else {
//       currentItem.value = data[i];
//       break;
//     }
//   }
// };
/**
 * @description: 点击节点
 * @param {*} row
 * @return {*}
 */
const handleNodeClick = async (row: TestCaseItem) => {
  console.log(row);
  if (row.id === currentItem.value.id) return;
  treeRef.value?.setCurrentKey(currentItem.value.id);
  const hasErr = updataScrollChange();
  if (hasErr) {
    await ElMessageBox.confirm("当前表单输入不规范，切换将失去当前修改，确认放弃本次修改?", "提示", { type: "warning" });
  } else if (oldDataString.value !== JSON.stringify(nodeData.value)) {
    updateTestCaseConfig({ caseId: currentItem.value.id || "", config: nodeData.value }, { taskId: props.taskInfo.id });
    ElMessage.success("参数更新成功");
  }
  treeRef.value?.setCurrentKey(row.id);
  currentItem.value = row;
  getNodeData();
};

/**
 * @description: 更新滚动条
 * @return {*}
 */
const updataScrollChange = () => {
  const errorEle = nodeTreeRef.value?.$el.querySelector(".node-valid-error");
  const heightTop = errorEle && (errorEle as HTMLElement).offsetTop;
  const scrollEle = nodeTreeRef.value?.scrollbar;
  (scrollEle as any).setScrollTop(heightTop || 0);
  return !!errorEle;
};
/**
 * @description: 完成任务创建
 */
const handleFinish = async () => {
  try {
    btnLoading.value = true;
    const hasErr = updataScrollChange();
    if (hasErr) {
      ElMessage.error("您有表单内容没有按规范填写");
      return;
    }
    let chooseId: TreeKey[] = treeRef.value?.getCheckedKeys() || []; // 勾选的测试例名称，全部传[]
    const halfChooseId = treeRef.value?.getHalfCheckedKeys() || [];
    const testCaseIds = [...halfChooseId, ...chooseId];
    if (!testCaseIds.length) {
      ElMessage.error("请选择测试用例");
      return;
    }
    const taskId = String(props.taskInfo.id || "");
    if (oldDataString.value !== JSON.stringify(nodeData.value)) {
      await updateTestCaseConfig({ caseId: currentItem.value.id || "", config: nodeData.value }, { taskId });
      ElMessage.success("参数更新成功");
    }
    await setSelectCases({ testCaseIds }, { taskId });
    await completeCreateTask(undefined, { taskId });
    ElMessage.success("任务创建成功");
    emit("reset");
    await routerLinkTestView("/testView?taskId=" + taskId);
  } finally {
    btnLoading.value = false;
  }
};
</script>

<style lang="scss" scoped>
.tree-form {
  height: 100%;
  display: flex;

  .left-view {
    background-color: #f3f3f3;
    height: 100%;
    min-width: 180px;

    :deep(.el-scrollbar) {
      .el-tree {
        --el-fill-color-blank: transparent;
        padding-top: 5px;

        &.el-tree--highlight-current {
          .el-tree-node {
            &>.el-tree-node__content {
              &:hover {
                background: #e4e6f1;
                color: #333;
              }
            }

            &.is-current {
              &>.el-tree-node__content {
                background: #e4e6f1;
                color: #008efa;
              }
            }
          }
        }

        .el-tree-node {
          .el-tree-node__content {
            height: 32px;

            >label.el-checkbox {
              margin-right: 5px;
            }

            .custom-tree-node {
              width: calc(100% - 54px);
              display: flex;
              align-items: center;

              .svg-icon {
                margin-right: 5px;
              }
            }

            .el-checkbox__inner {
              --el-checkbox-input-border: 1px solid #ccc;
            }
          }
        }

        .el-tree-node__expand-icon {
          color: #666;
          font-weight: bold;
          margin-left: 10px;

          &.is-leaf {
            color: transparent;
            opacity: 0;
          }
        }
      }
    }
  }

  .right-view {
    padding: 20px 20px 20px 10px;

    .node-tree {
      height: calc(100% - 80px);
    }

    .btn-box {
      text-align: center;
      padding-top: 20px;
    }
  }
}
</style>
